﻿using System;
using System.Linq;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Slma.OData.Factory;

// Author: Miroslav Matula m.matula@alutam.cz 
// Date : 9.9.2010

namespace Slma.OData
{
  public class Entity<T_ODataEntityType>:Entity
  {
    /// <summary>
    /// Volá se při generování typu v ClassFactory
    /// Inicializace seznamu property, které jsou generovány podle T_ODataEntityType. 
    /// </summary>
    /// <param name="propertyList_"></param>
    public static void InitStaticFields(EntityPropertyDefList propertyList_)
    {
      if(_stCdef != null) return; // pouze jednou
      var cdef = new CDef();
      // vytvořím def. columns
      cdef._propertyList = new Factory.EntityPropertyDefList();
      foreach(var item in propertyList_) {
        cdef._propertyList.Add(new Factory.EntityPropertyDef() {
          //PropertyName = ca.ColumnName,
          PropertyType = item.PropertyType,
          PropertyName = item.PropertyName,
          AllowDBNull = item.AllowDBNull,
          MaxLength = item.MaxLength,
          Validate = item.Validate
        });
      }
      // nastavím default hodnoty
      cdef._defaultValues = new object[cdef._propertyList.Count];
      for(int i = 0; i < cdef._propertyList.Count; i++) {
        //if (_columnList[i].ColumnType.IsValueType)
        //{
        cdef._defaultValues[i] = GetDefaultEntityValue(cdef._propertyList[i].PropertyType);
        //}
      }
      _stCdef = cdef;
    }
    private static CDef _stCdef;// Container Definice

    protected override CDef DefProperty { get { return _stCdef; } }// Container Definice
    //----
    //public new Entity<T_ODataEntityType> Clone()
    //{
    //  Entity<T_ODataEntityType> en = Activator.CreateInstance(this.GetType()) as Entity<T_ODataEntityType>;
    //  en._data = _data;
    //  en._dataOrigin = _dataOrigin;
    //  en._entityState = _entityState;
    //  return en;
    //}
    #region -- ODataEntity ---------------
    // nastaví data z ODataEntity
    public void SetData(T_ODataEntityType data_)
    {
      Type thisType = this.GetType();
      var propInfo = typeof(T_ODataEntityType).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
      foreach(var item in propInfo) {
        thisType.GetProperty(item.Name)
        .SetValue(this, item.GetValue(data_, null), null);
      }
    }
    public T_ODataEntityType CreateODataEntity()
    {
      var res = Activator.CreateInstance<T_ODataEntityType>();
      // nastavím hodnoty
      Type thisType = this.GetType();
      var propInfo = typeof(T_ODataEntityType).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
      foreach(var item in propInfo) {
        var pro = thisType.GetProperty(item.Name);
        var val = pro.GetValue(this, null);
        item.SetValue(res, val, null);
      }
      return res;
    }

    #endregion

  }
}
